import { defineComponent, ref, resolveDirective, watch, withDirectives } from 'vue'
import {
  ElButton,
  ElCol,
  ElDialog,
  ElInput,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElRow,
  ElTooltip,
  ElTree,
  ElTreeSelect,
} from 'element-plus'
import { createForm, isField, onFieldInit } from '@formily/core'
import { connect, mapProps } from '@formily/vue'
import { FormGrid, FormItem, FormLayout, Input, Select } from '@formily/element-plus'
import { useRouter } from 'vue-router'
import studentSchema from './schema/studentSchema'
import Import from './import'
import Export from './export'
import type { User } from '@/types/user'
import type { Tree } from '@/api/system/user'
import { deptTreeSelect, getUser, listUser, resetUserPwd, updateUser } from '@/api/system/user'
import DictTag from '@/components/DictTag/index.vue'
import usePageTable from '@/hooks/usePageTable'
import { useDict } from '@/utils/dict'
import SchemaForm from '@/components/SchemaForm'

export default defineComponent({
  setup() {
    const { sys_user_sex, sys_student_status } = useDict('sys_user_sex', 'sys_student_status')
    const hasPermi = resolveDirective('hasPermi')

    /** 列表逻辑 */
    const {
      QueryForm,
      Table,
      queryParams,
      handleSearch,
    } = usePageTable<User>(
      {
        getList: listUser,
        fields: [
          {
            title: '身份证号',
            key: 'userName',
            type: 'Input',
          },
          {
            title: '姓名',
            key: 'nickName',
            type: 'Input',
          },
          {
            title: '状态',
            key: 'status',
            type: 'Select',
            enums: () => sys_student_status.value.map(
              item =>
                <ElOption label={item.label} value={item.value} key={item.value}>{item.label}</ElOption>,
            ),
          },
        ],
        initValues: {
          userType: '学生',
          pageSize: 10,
          pageNum: 1,
        },
      },
      [
        {
          key: 'userName',
          title: '身份证号',
          props: {
            align: 'center',
          },
        },
        {
          key: 'nickName',
          title: '姓名',
        },
        {
          key: 'sex',
          title: '性别',
          render: row => <DictTag value={row.sex} options={sys_user_sex.value} />,
        },
        {
          key: 'phonenumber',
          title: '手机号码',
        },
        {
          key: 'status',
          title: '状态',
          render: row => <DictTag value={row.status} options={sys_student_status.value} />,
        },
        {
          key: 'remark',
          title: '情况说明',
        },
        {
          key: 'operate',
          title: '操作',
          render: row => (
            row.userId !== 1 && (
              <>
                <ElTooltip content="修改" placement="top">
                  {withDirectives(<ElButton link type="primary" icon="Edit" onClick={() => handleUpdate(row)} />, [[hasPermi, ['system:user:edit']]])}
                </ElTooltip>
                <ElTooltip content="学生信息管理" placement="top">
                  {withDirectives(<ElButton link type="primary" icon="CircleCheck" onClick={() => handleStudentDetail(row)} />, [[hasPermi, ['system:user:edit']]])}
                </ElTooltip>
                <ElTooltip content="重置密码" placement="top">
                  {withDirectives(<ElButton link type="primary" icon="Key" onClick={() => handleResetPwd(row)} />, [[hasPermi, ['system:user:resetPwd']]])}
                </ElTooltip>
              </>
            )
          ),
        },
      ],
    )
    void handleSearch()

    /** 部门树逻辑 */
    const deptOptions = ref<Tree[]>()
    const deptTreeRef = ref<InstanceType<typeof ElTree>>()
    const deptName = ref('')
    watch(deptName, (val) => {
      deptTreeRef.value?.filter(val)
    })
    function filterNode(value: string, data: Tree) {
      if (!value)
        return true
      return data.label.includes(value)
    }
    function handleNodeClick(data: Tree) {
      queryParams.value.deptId = data.id
      void handleSearch()
    }
    async function getDeptTree() {
      const { data } = await deptTreeSelect()
      deptOptions.value = (data && data[0] && data[0].children) || []
    }
    void getDeptTree()

    /** 新增修改逻辑 */
    const open = ref(false)
    const title = ref('')
    const form = createForm<Partial<User>>({
      effects: () => {
        onFieldInit('layout.gird.deptId', async (field) => {
          if (isField(field))
            field.dataSource = deptOptions.value!
        })
        onFieldInit('layout.gird.sex', (field) => {
          if (isField(field))
            field.dataSource = sys_user_sex.value
        })
        onFieldInit('layout.gird.status', (field) => {
          if (isField(field))
            field.dataSource = sys_student_status.value
        })
      },
    })
    const TreeSelect = connect(
      ElTreeSelect,
      mapProps(
        { dataSource: 'data', value: 'modelValue' },
        props => ({
          ...props,
          props: { value: 'id', label: 'label', children: 'children' },
          valueKey: 'id',
          checkStrictly: true,
        }),
      ),
    )
    async function submitForm() {
      await form.submit((values) => {
        if (values.userId)
          return updateUser(values as Partial<User> & { useId: number })
      })
      open.value = false
      void handleSearch()
    }
    async function handleUpdate(row: User) {
      const userId = row.userId
      const { data } = await getUser(userId)
      form.setValues(data, 'overwrite')
      open.value = true
      title.value = '修改学生信息'
    }

    /** 列表操作 */
    const router = useRouter()
    function handleStudentDetail(row: User) {
      void router.push({
        path: `/student/${row.userName}`,
      })
    }
    async function handleResetPwd(row: User) {
      const { action, value } = await ElMessageBox.prompt(`请输入"${row.userName}"的新密码`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,
        inputPattern: /^.{5,20}$/,
        inputErrorMessage: '用户密码长度必须介于 5 和 20 之间',
      })
      if (action === 'confirm') {
        await resetUserPwd(row.userId, value)
        ElMessage.success(`修改成功，新密码是：${value}`)
      }
    }

    const exportOpen = ref(false)
    const importOpen = ref(false)

    return () => (
      <div class="p-2 md:p-4 h-full">
        <ElRow gutter={20} class="h-full">
          <ElCol span={4} xs={24} class="h-full flex-col overflow-hidden" style="display: flex;">
            <div class="px-2">
              <ElInput
                placeholder="请输入部门名称"
                clearable
                v-model={deptName.value}
                prefix-icon="Search"
                style="margin-bottom: 20px"
              />
            </div>
            <div class="flex-1 h-0 overflow-auto w-full">
              <ElTree
                class="overflow-x-auto w-full"
                props={{ label: 'label', children: 'children' }}
                expand-on-click-node={false}
                filter-node-method={filterNode}
                node-key="id"
                highlight-current
                onNode-click={handleNodeClick}
                data={deptOptions.value}
                ref={deptTreeRef}
              />
            </div>
          </ElCol>
          <ElCol span={20} xs={24} class="h-full flex-col" style="display: flex;">
            {QueryForm && <QueryForm />}
            <ElRow gutter={10} class="mb-4">
              <ElCol span={1.5}>
                {withDirectives(
                  <ElButton
                    type="warning"
                    plain
                    icon="Upload"
                    onClick={() => importOpen.value = true}
                  >
                    导入
                  </ElButton>,
                  [[hasPermi, ['system:user:export']]],
                )}
              </ElCol>
              <ElCol span={1.5}>
                {withDirectives(
                  <ElButton
                    type="warning"
                    plain
                    icon="Download"
                    onClick={() => exportOpen.value = true}
                  >
                    导出
                  </ElButton>,
                  [[hasPermi, ['system:user:export']]],
                )}
              </ElCol>
            </ElRow>
            <Table />
          </ElCol>
        </ElRow>

        <ElDialog v-model={open.value} title={title.value} width="750px" append-to-body>
          {{
            default: () => <SchemaForm form={form} schema={studentSchema} components={{ FormGrid, Input, Select, TreeSelect, FormItem, FormLayout }} />,
            footer: () => (
              <div class="dialog-footer">
                <ElButton type="primary" onClick={submitForm}>
                  确 定
                </ElButton>
                <ElButton onClick={() => open.value = false}>
                  取 消
                </ElButton>
              </div>
            ),
          }}
        </ElDialog>
        <Export v-model={exportOpen.value} deptOptions={deptOptions.value} />
        <Import v-model={importOpen.value} />
      </div>
    )
  },
})
